package com.dangz.dans.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dangz.dans.model.wx.SubscribeInfo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author dangz
 * @since 2018/1/29 14:18
 */
public class WxUtils {
    private final static Logger logger = LoggerFactory.getLogger(WxUtils.class);
    private final static String WX_ACCESS_TOKEN = "WX_ACCESS_TOKEN";
    private final static Integer USER_OPENID_COUNT = 10000;
    //获取ACCESS_TOKEN的URL
    private final static String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential";
    //获取关注者openid的URL
    private final static String USER_OPENID_URL = "https://api.weixin.qq.com/cgi-bin/user/get";
    private final static String USER_INFO_URL = "https://api.weixin.qq.com/cgi-bin/user/info";
    private final static String TEMPLATE_URL = "https://api.weixin.qq.com/cgi-bin/message/template/send";//?access_token=ACCESS_TOKEN
    private final static String MENU_CREATE_URL = " https://api.weixin.qq.com/cgi-bin/menu/create";//?access_token=ACCESS_TOKEN


    /**
     * 获取ACCESS_TOKEN
     */
    public static String getAccessToken(String appid, String secret, RedisUtil redisUtil){
        //appid=APPID&secret=APPSECRET
        JSONObject token = null;
        StringBuffer sb = new StringBuffer(ACCESS_TOKEN_URL);
        String wx_token = WX_ACCESS_TOKEN + ":" + appid;
        try {
            if (redisUtil.exists(wx_token)) {
                return redisUtil.get(wx_token).toString();
            }
            sb.append("&").append("appid").append("=").append(appid);
            sb.append("&").append("secret").append("=").append(secret);
            String tokenStr = HttpHander.httpGet(sb.toString());
            logger.info("tokenStr:{}, ACCESS_TOKEN_URL:{}", tokenStr, sb.toString());
            if (StringUtils.isNotEmpty(tokenStr)) {
                token = JSON.parseObject(tokenStr);
                redisUtil.set(wx_token, token.getString("access_token"), 7200L);
            }
            //开发时需存库处理，每日获取token次数有限（500次）, 这里使用redis
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        return token.getString("access_token");
    }

    /**
     * 获取粉丝列表
     */
    public static List<SubscribeInfo> getOpenIdInfo(String appid, String secret, RedisUtil redisUtil, String nextOpenid){
//        ?access_token=ACCESS_TOKEN&next_openid=NEXT_OPENID
        List<SubscribeInfo> list = null;
        JSONObject openidObj = getOpenIds(appid, secret, redisUtil, nextOpenid);
        JSONObject obj = null;
        SubscribeInfo subscribeInfo = null;
        if (openidObj != null) {
            list = new ArrayList<>();
            String next_openid = openidObj.getString("next_openid");
            Integer count = openidObj.getInteger("count");
            Integer total = openidObj.getInteger("total");

            obj  = openidObj.getJSONObject("data");
            JSONArray array = obj.getJSONArray("openid");
            logger.info("array：{}, count:{}", array.size(), count);
            for (int i = 0; i < count; i++) {
                obj = getUserInfo(appid, secret, redisUtil, array.get(i).toString());
                if (obj.get("errcode") != null){
                    break;
                }
//                logger.info("obj:{}", obj.toJSONString());
                obj.remove("tagid_list");
                subscribeInfo = JSON.parseObject(obj.toJSONString(), SubscribeInfo.class);
                subscribeInfo.setSubscribe_time(formatTime(String.valueOf(subscribeInfo.getSubscribe_time())));
                list.add(subscribeInfo);
                //可根据自己需求改变存储方式
            }
            if (total > count && USER_OPENID_COUNT > count) {
                getOpenIdInfo(appid, secret, redisUtil, next_openid);
            }
        }
        return list;
    }

    /**
     * 获取用户信息
     */
    public static JSONObject getUserInfo(String appid, String secret, RedisUtil redisUtil, String openid){
//        ?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
        JSONObject obj = null;
        String token = getAccessToken(appid, secret, redisUtil);
        StringBuffer sb = new StringBuffer(USER_INFO_URL);
        sb.append("?").append("access_token").append("=").append(token);
        sb.append("&").append("openid").append("=").append(openid);
        sb.append("&").append("lang").append("=").append("zh_CN");
        try {
            String userInfo = HttpHander.httpGet(sb.toString());
//            logger.info("userInfo:{}", userInfo);
            if (StringUtils.isNotEmpty(userInfo)) {
                obj = JSONObject.parseObject(userInfo);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return obj;
    }

    /**
     * 获取openids
     */
    public static JSONObject getOpenIds(String appid, String secret, RedisUtil redisUtil, String nextOpenid){
        JSONObject obj = null;
        JSONArray array = null;
        String token = getAccessToken(appid, secret, redisUtil);
        StringBuffer sb = new StringBuffer(USER_OPENID_URL);
        sb.append("?").append("access_token").append("=").append(token);
        sb.append("&").append("next_openid").append("=").append(nextOpenid);
        JSONObject openidObj = null;
        try {
            String openidStr = HttpHander.httpGet(sb.toString());
            logger.info("openidStr:{}", openidStr);
            if (StringUtils.isNotEmpty(openidStr)) {
                obj = JSONObject.parseObject(openidStr);
                /*obj.put("next_openid", openidObj.getString("next_openid"));
                obj.put("count", openidObj.getInteger("count"));
                obj.put("total", openidObj.getInteger("total"));
                obj.put("data", openidObj.getJSONArray("data"));*/
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return obj;
    }

    /**
     * 发送模板消息
     */
    public static void sendTemplate(String appid, String secret, RedisUtil redisUtil, JSONObject obj) {
        String token = getAccessToken(appid, secret, redisUtil);
        StringBuffer sb = new StringBuffer(TEMPLATE_URL);
        sb.append("?").append("access_token").append("=").append(token);
        try {
            String str = HttpHander.jsonPost(sb.toString() , obj);
            if (StringUtils.isNotEmpty(str)) {
                JSONObject o = JSON.parseObject(str);
                if (o.getString("errmsg").equals("ok") && o.getInteger("errcode") == 0) {
                    logger.info("发送模板消息成功！");
                } else {
                    sendTemplate(appid, secret, redisUtil, obj);
                    logger.info("发送模板消息失败！");
                }
            } else {
                logger.info("发送模板消息请求失败！");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建微信菜单
     */
    public static boolean createMenu(String appid, String secret, RedisUtil redisUtil, JSONObject obj){
        boolean isTrue = false;
        String token = getAccessToken(appid, secret, redisUtil);
        StringBuffer sb = new StringBuffer(MENU_CREATE_URL);
        sb.append("?").append("access_token").append("=").append(token);
        try {
            String str = HttpHander.jsonPost(sb.toString() , obj);
            if (StringUtils.isNotEmpty(str)) {
                JSONObject o = JSON.parseObject(str);
                if (o.getString("errmsg").equals("ok")) {
                    logger.info("创建菜单成功！");
                    isTrue = true;
                } else {
                    logger.info("创建菜单失败！");
                }
            } else {
                logger.info("创建菜单请求失败！");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return isTrue;
    }

    /**
     * 将微信消息中的CreateTime转换成标准格式的时间（yyyy-MM-dd HH:mm:ss）
     * @param createTime 消息创建时间
     */
    public static String formatTime(String createTime) {
        // 将微信传入的CreateTime转换成long类型，再乘以1000
        long msgCreateTime = Long.parseLong(createTime) * 1000L;
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return format.format(new Date(msgCreateTime));

    }

    public static void main(String[] arg0) throws Exception {
        String appid = "wx7c0b6d75e67cd4c1";
        String secret = "36cf9c15b8371fb018c3131947e411e5";
        //获取签名signature
        /*String str = SHA1.getSignature("1231231","13","1231");
        logger.info("getSignature:{}", str);*/

    }
}
